package edos.prm.artifact;

/**
 * The {@code AttributeMatcher} is an engine whose role is to execute a
 * matching operation on two attribute objects.
 * <p>
 * The engine is called by implementations of the {@code lookUp} operation for
 * artifact management. 
 * 
 * @version 1.0
 */
public final class AttributeMatcher {
	
	static {
		matcher = new AttributeMatcher();
	}
	
	private AttributeMatcher(){}
	
	private static AttributeMatcher matcher;
	
	/**
	 * Return an attribute matcher.
	 * 
	 * @return an instance of the AttributeMatcher class
	 */
	public static AttributeMatcher getInstance() {
		return matcher;
	}
	
	/**
	 * Compare two attributes using the matching procedure.
	 * <p>
	 * Attribute a1 matches with a2 if:
	 * <ul>
	 * <li>If a1 {@code equals} a2, or </li>
	 * <li>If the classes of a1 and a2 are assignable, and implement the
	 * {@code Comparable} interface, and a1 is less than or equal to a2 using
	 * the {@code compareTo} method.</li>
	 * </ul>
	 * @param a1 attribute object
	 * @param a2 attribute object
	 * @return true if a1 matches a2
	 */
	@SuppressWarnings("unchecked")
	public boolean match(Object a1, Object a2) {
		if ( !a1.getClass().isAssignableFrom(a2.getClass()) )
			return false;
		if ( a1.equals(a2) )
			return true;
		if ( a2 instanceof java.lang.Comparable ) {
			Comparable<Comparable<?>> c1, c2;
			c1 = (Comparable<Comparable<?>>)a1;
			c2 = (Comparable<Comparable<?>>)a2;
			return ( c1.compareTo(c2) <= 0);
		}
		return false;
	}
}
